package com.sjsu.cmpe239.collborativeFilteringRecomender;

import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.model.file.FileDataModel;
import org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel;
import org.apache.mahout.cf.taste.impl.recommender.slopeone.SlopeOneRecommender;
import org.apache.mahout.cf.taste.model.JDBCDataModel;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;

import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource;
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import com.sjsu.cmpe239.Constants;
import com.sjsu.cmpe239.beans.Movie;
import com.sjsu.cmpe239.connection.ConnectionPool;
import com.sjsu.cmpe239.googleservice.ImageGenerater;

public class Recommender239 {

	/**
	 * @param args
	 * @throws Exception
	 */

	public List<Movie>  recomendMovies(int userID) throws Exception {
		// TODO Auto-generated method stub

		Set<Long> moviesSet = movieRecommendations(userID);
		
		List<Movie> movieList=listMovies(moviesSet);
		System.out.println("movie list size: "+movieList.size());
		Iterator<Movie> it = movieList.iterator();
		
		while (it.hasNext()) {
			System.out.println(it.next().getMovieName() + ",");
			
		}
		return movieList;
	}
	
	public static void main(String[] args) throws Exception {
		// TODO Auto-generated method stub

		Set<Long> moviesSet = movieRecommendations(1);
		
		List<Movie> movieList=listMovies(moviesSet);
		System.out.println("movie list size: "+movieList.size());
		Iterator<Movie> it = movieList.iterator();
		
		while (it.hasNext()) {
			System.out.println(it.next().getMovieName() + ",");
		}
	}

	public static FileDataModel buildDataModel() throws IOException {
		MysqlDataSource dataSource = new MysqlConnectionPoolDataSource();
		dataSource.setServerName("localhost");
		dataSource.setUser("root");
		dataSource.setPassword("deepika");
		dataSource.setDatabaseName("239_movie_rec_schema");

		return new FileDataModel(new File("C:/Data/ratings.csv"));
		//return new MySQLJDBCDataModel(dataSource, "taste_preferences",
		//		"user_id", "item_id", "preference", "time");

	}

	public static Set<Long> movieRecommendations(long userId)
			throws TasteException, InterruptedException, IOException {
		System.out.println("UserId: " + userId);
		Set<Long> recommendationSet = new HashSet<Long>(10);
		List<RecommendedItem> recommendationItemList = new ArrayList<RecommendedItem>();
		FileDataModel model = buildDataModel();

		/******************* Start: GenericUserBasedRecommender *****************************/
		/*
		 * System.out.println("1 " ); UserSimilarity similarity = new
		 * LogLikelihoodSimilarity(model); UserNeighborhood neighborhood = new
		 * NearestNUserNeighborhood(2, similarity, model); final
		 * GenericUserBasedRecommender userBasedRecommender = new
		 * GenericUserBasedRecommender( model, neighborhood, similarity);
		 * List<RecommendedItem> userBasedRecommendations = userBasedRecommender
		 * .recommend(userId, 3);
		 * recommendationItemList.addAll(userBasedRecommendations);
		 * System.out.println("2 " );
		 */
		/******************* End: GenericUserBasedRecommender *******************************/

		/******************* Start: SVDRecommender *******************************/
		/*
		 * SVDRecommender SVDRecommenderObj = new SVDRecommender(model, new
		 * ALSWRFactorizer(model, 5, 0.05, 3)); List<RecommendedItem>
		 * svdRecommendations = SVDRecommenderObj.recommend( userId, 3);
		 * recommendationItemList.addAll(svdRecommendations);
		 */
		/******************* End: SVDRecommender *******************************/

		/******************* Start: SlopeOneRecommender *******************************/
		SlopeOneRecommender slopeOneRecommenderObj = new SlopeOneRecommender(
				model);
		List<RecommendedItem> slopeOneRecommendations = slopeOneRecommenderObj
				.recommend(userId, 10);
		recommendationItemList.addAll(slopeOneRecommendations);
		/******************* End: SlopeOneRecommender *******************************/

		for (int i = 0; i < recommendationItemList.size(); i++) {
			recommendationSet.add(recommendationItemList.get(i).getItemID());
			// System.out.println(recommendationItemList.get(i).getItemID() +
			// ",");
		}
		return recommendationSet;
	}

	public static List<Movie> listMovies(Set<Long> movieIdSet) {
		Connection connection = null;
		Statement stmt = null;
		ConnectionPool conPoolObj = ConnectionPool.getConnectionPoolInstance();
		ResultSet resultSet;
		List<Movie> moviesList = new ArrayList<Movie>();
		try {
			connection = conPoolObj.getConnection();
			stmt = connection.createStatement();
			Iterator<Long> it = movieIdSet.iterator();
			String movieIds = "";
			while (it.hasNext()) {
				if (movieIds == "") {
					movieIds = it.next().toString();
				} else {
					movieIds = movieIds + "," + it.next();
				}
			}

			System.out.println("movieIds= " + movieIds);
			String strQuery = "select * from movies where id in ( " + movieIds
					+ ")";
			resultSet = stmt.executeQuery(strQuery);
			Movie movieObj = null;
			String genres = "";
			while (resultSet.next()) {

				movieObj = new Movie();
				movieObj.setMovieId(resultSet.getInt(1) + "");
				movieObj.setMovieName(resultSet.getString(2) + "");
				movieObj.setDate(resultSet.getString(3) + "");
				String movieName = resultSet.getString(2);
				ImageGenerater imggen = new ImageGenerater();
				movieObj.setImageURL(imggen.getURLForMovie(movieName));

				if (resultSet.getInt(6) == 1) {
					genres += Constants.genre[0] + " ";
				}
				if (resultSet.getInt(7) == 1) {
					genres += Constants.genre[1] + " ";
				}
				if (resultSet.getInt(8) == 1) {
					genres += Constants.genre[2] + " ";
				}
				if (resultSet.getInt(9) == 1) {
					genres += Constants.genre[3] + " ";
				}
				if (resultSet.getInt(10) == 1) {
					genres += Constants.genre[4] + " ";
				}
				if (resultSet.getInt(11) == 1) {
					genres += Constants.genre[5] + " ";
				}
				if (resultSet.getInt(12) == 1) {
					genres += Constants.genre[6] + " ";
				}
				if (resultSet.getInt(13) == 1) {
					genres += Constants.genre[7] + " ";
				}
				if (resultSet.getInt(14) == 1) {
					genres += Constants.genre[8] + " ";
				}
				if (resultSet.getInt(15) == 1) {
					genres += Constants.genre[9] + " ";
				}
				if (resultSet.getInt(16) == 1) {
					genres += Constants.genre[10] + " ";
				}
				if (resultSet.getInt(17) == 1) {
					genres += Constants.genre[11] + " ";
				}
				if (resultSet.getInt(18) == 1) {
					genres += Constants.genre[12] + " ";
				}
				if (resultSet.getInt(19) == 1) {
					genres += Constants.genre[13] + " ";
				}
				if (resultSet.getInt(20) == 1) {
					genres += Constants.genre[14] + " ";
				}
				if (resultSet.getInt(21) == 1) {
					genres += Constants.genre[15] + " ";
				}
				if (resultSet.getInt(22) == 1) {
					genres += Constants.genre[16] + " ";
				}
				if (resultSet.getInt(23) == 1) {
					genres += Constants.genre[17] + " ";
				}

				movieObj.setGenres(genres);

				moviesList.add(movieObj);
			}

		} catch (SQLException e) {

		} finally {
			if (stmt != null) {
				try {
					stmt.close();
				} catch (SQLException sqe) {

				}
			}
			if (connection != null) {
				conPoolObj.free(connection);
			}
		}

		return moviesList;
	}

	
	
}